﻿namespace ScrumLite.WebUx.Tests
{
    using System;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using ScrumLite.Services;
    using ScrumLite.Services.Contracts;
    using ScrumLite.WebUx.Controllers;
    using ScrumLite.WebUx.Models;
    using System.Globalization;
    using System.Web.Mvc;


    /// <summary>
    /// Summary description for ProjectsControllerFixture
    /// </summary>
    [TestClass]
    public class ProjectsControllerFixture
    {
        [TestMethod]
        public void ShouldAddNewProjectOnSaveWithEmptyProjectId()
        {
            MockProjectsService service = new MockProjectsService();
            TestableProjectsController controller = new TestableProjectsController(service);
            MockHelpers.SetupMocks(controller);

            controller.Save(Guid.Empty.ToString(), "New Project", "some URL", "some URL", "Test Group", DateTime.Now, DateTime.Now);

            Assert.IsTrue(service.AddProjectCalled);
            Assert.AreEqual("New Project", service.ProjectAdded.Name);
        }

        [TestMethod]
        public void ShouldUpdateProjectWhenAProjectIdIsSpecified()
        {
            MockProjectsService service = new MockProjectsService();
            TestableProjectsController controller = new TestableProjectsController(service);
            MockHelpers.SetupMocks(controller);

            controller.Save(MockHelpers.KnownProjectId.ToString(), "ScrumLite", "some URL", "some URL", "Test Group", DateTime.Now, DateTime.Now);

            Assert.IsTrue(service.UpdateProjectCalled);
            Assert.AreEqual(MockHelpers.KnownProjectId, service.ProjectAdded.Id);
            Assert.AreEqual("ScrumLite", service.ProjectAdded.Name);
        }

        [TestMethod]
        public void ShouldControllerPassDefaultProjectValuesToView()
        {
            MockProjectsService service = new MockProjectsService();
            TestableProjectsController controller = new TestableProjectsController(service);
            MockHelpers.SetupMocks(controller);

            controller.New();

            Assert.IsNotNull(controller.Data);
            Assert.IsInstanceOfType(controller.Data, typeof(ProjectsWriteViewData));
            Assert.AreEqual("new-project", ((ProjectsWriteViewData)controller.Data).Project.Name);
            Assert.AreEqual(string.Format(CultureInfo.InvariantCulture,"{0}/{1}", ConfigurationManager.AppSettings["defaultRootProjectRepository"], "new-project"), ((ProjectsWriteViewData)controller.Data).Project.RepositoryUri);
        }

        [TestMethod]
        public void ShouldShowAllRolesForAProject()
        {
            MockProjectsService projects = new MockProjectsService();
            MockProfileService profiles = new MockProfileService();
            MockRolesService roles = new MockRolesService();
            
            TestableProjectsController controller = new TestableProjectsController(projects, profiles, roles);
            MockHelpers.SetupMocks(controller);

            controller.ReadRoles("AF06A611-12CE-4C06-B3AD-E2754D12D516");
            Assert.IsTrue(roles.GetProjectRolesCalled);
            Assert.AreEqual(4,((ProjectRolesViewData)controller.Data).Roles.Count);
            Assert.IsNotNull(((ProjectRolesViewData)controller.Data).ProjectId);
            Assert.IsNotNull(((ProjectRolesViewData)controller.Data).ProjectName);
            Assert.IsNotNull(((ProjectRolesViewData)controller.Data).Abilities);              
        }

        [TestMethod]
        public void ShouldShowAbilitiesForAProjectRole()
        {
            MockProjectsService projects = new MockProjectsService();
            MockProfileService profiles = new MockProfileService();
            MockRolesService roles = new MockRolesService();

            TestableProjectsController controller = new TestableProjectsController(projects, profiles, roles);
            MockHelpers.SetupMocks(controller);

            controller.Abilities(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
            Assert.IsTrue(roles.GetAbilitiesCalled);
            Assert.AreEqual(5,((RoleAbilitiesViewData)controller.Data).Abilities.Count);
            Assert.IsNotNull(((RoleAbilitiesViewData)controller.Data).Role);
        }

        [TestMethod]
        public void ShouldShowCurrentProjects()
        {
            MockProjectsService projects = new MockProjectsService();
            TestableProjectsController controller = new TestableProjectsController(projects);
            MockHelpers.SetupMocks(controller);

            controller.List();

            Assert.AreEqual(12, (((ProjectListViewData)controller.Data).Projects.Count));
        }

        [TestMethod]
        public void ShouldShowHistoricProjects()
        {
            MockProjectsService projects = new MockProjectsService();
            TestableProjectsController controller = new TestableProjectsController(projects);
            MockHelpers.SetupMocks(controller);

            controller.ListHistoric();

            Assert.AreEqual(7, (((ProjectListViewData)controller.Data).Projects.Count));            
        }

        [TestMethod]
        public void ShouldShowTeamList()
        {
            MockProjectsService projects = new MockProjectsService();
            TestableProjectsController controller = new TestableProjectsController(projects);
            MockHelpers.SetupMocks(controller);

            controller.Team("AF06A611-12CE-4C06-B3AD-E2754D12D516");

            Assert.AreEqual(2, ((TeamListViewData)controller.Data).InternalPersons.Count);
            Assert.AreEqual(1, ((TeamListViewData)controller.Data).ExternalPersons.Count);
        }

        [TestMethod]
        public void ShouldShowPeopleTeamList()
        {
            MockProjectsService projects = new MockProjectsService();
            TestableProjectsController controller = new TestableProjectsController(projects);
            MockHelpers.SetupMocks(controller);

            controller.MakeTeam("AF06A611-12CE-4C06-B3AD-E2754D12D516");

            Assert.IsNotNull(controller.Data);
            Assert.IsInstanceOfType(controller.Data, typeof(PeopleTeamViewData));
            Assert.AreEqual(5, ((PeopleTeamViewData)controller.Data).People.Count);
            Assert.IsNotNull(((PeopleTeamViewData)controller.Data).ProjectId);
            Assert.IsNotNull(((PeopleTeamViewData)controller.Data).ProjectName);
        }

        [TestMethod]
        public void ShouldShowComplianceCheck()
        {
            MockProjectsService projects = new MockProjectsService();
            TestableProjectsController controller = new TestableProjectsController(projects);
            MockHelpers.SetupMocks(controller);

            controller.CChecker("AF06A611-12CE-4C06-B3AD-E2754D12D516");

            Assert.IsNotNull(controller.Data);
            Assert.IsInstanceOfType(controller.Data, typeof(ProjectCheckerViewData));
            Assert.AreEqual(1, ((ProjectCheckerViewData)controller.Data).Check.Count);
            Assert.IsFalse(((ProjectCheckerViewData)controller.Data).Check[0].Status);
            Assert.AreEqual("WorkAreas", ((ProjectCheckerViewData)controller.Data).Check[0].PropertyChecked.Trim());
            Assert.AreEqual(1, ((ProjectCheckerViewData)controller.Data).Check[0].Errors.Count);
            Assert.IsNotNull(((ProjectCheckerViewData)controller.Data).ProjectId);
            Assert.IsNotNull(((ProjectCheckerViewData)controller.Data).ProjectName);
        }

        [TestMethod]
        public void ShouldAddRole()
        {
            MockProjectsService projects = new MockProjectsService();
            MockProfileService profiles = new MockProfileService();
            MockRolesService roles = new MockRolesService();

            TestableProjectsController controller = new TestableProjectsController(projects, profiles, roles);
            MockHelpers.SetupMocks(controller);

            controller.AddRole("AF06A611-12CE-4C06-B3AD-E2754D12D516","Tester");

            Assert.IsTrue(roles.AddRoleToProjectCalled);
            Assert.AreEqual("Tester", roles.AddedRole);
        }

        [TestMethod]
        public void ShouldNotAddEmptyRole()
        {
            MockProjectsService projects = new MockProjectsService();
            MockProfileService profiles = new MockProfileService();
            MockRolesService roles = new MockRolesService();

            TestableProjectsController controller = new TestableProjectsController(projects, profiles, roles);
            MockHelpers.SetupMocks(controller);

            controller.AddRole("AF06A611-12CE-4C06-B3AD-E2754D12D516", "");

            Assert.IsFalse(roles.AddRoleToProjectCalled);
            Assert.IsNull(roles.AddedRole);
        }
    }

    class TestableProjectsController : ProjectsController
    {
        public object Data;

        public TestableProjectsController()
            : base( new MockRolesService(), new MockProjectsService(), new MockProfileService(), new MockAbilitiesService())
        {
        }

        public TestableProjectsController(IProjectsService service)
            : base(new MockRolesService(), service, new MockProfileService(), new MockAbilitiesService())
        {
        }

        public TestableProjectsController(IProjectsService service, IProfileService profile, IRolesService roles)
            : base(roles,service,profile, new MockAbilitiesService())
        {
        }

        protected override void RenderView(string viewName, string masterName, object viewData)
        {
            Data = viewData;
        }
    }
}
